package com.yilin.platform.controller;

import com.google.gson.reflect.TypeToken;
import com.yilin.platform.base_core.application.BaseController;
import com.yilin.platform.base_core.application.PageData;
import com.yilin.platform.base_core.application.ReturnData;
import com.yilin.platform.base_core.commons.utils.DateTimeUtil;
import com.yilin.platform.base_core.commons.utils.JsonUtil;
import com.yilin.platform.base_core.commons.utils.StreamUtil;
import com.yilin.platform.base_core.interceptor.EncryptInterceptor;
import com.yilin.platform.base_core.interceptor.NoBindingFilter;
import com.yilin.platform.base_core.interceptor.SkipLoginVerify;
import com.yilin.platform.base_core.tools.pab.entity.req.ReqBodyEDZ002;
import com.yilin.platform.base_core.tools.pab.entity.req.ReqBodyELC010;
import com.yilin.platform.base_core.tools.pab.entity.res.*;
import com.yilin.platform.entity.pab.PabDockingLog;
import com.yilin.platform.entity.pab.PabFileDownLoad;
import com.yilin.platform.entity.pab.PabTradeRecord;
import com.yilin.platform.service.IBankPabService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 平安银行
 * <p>
 * 接口调联控制层
 */
@RestController
@RequestMapping("/platform/pab/")
public class BankPabController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(BankPabController.class);

    @Resource
    private IBankPabService bankPabService;

    /**
     * 银行回调通知
     * 单笔转账指令查询 [4005]
     * 账务变动通知 [4013NT]
     * FILE04通知客户ERP文件上传、下载结果
     */
    @SkipLoginVerify
    @NoBindingFilter
    @RequestMapping(value = "pabCallNotice")
    public void pabCallNotice(HttpServletRequest request, HttpServletResponse response) {
        try {
            //处理银行通知的XML返回固定格式的头部信息
            logger.info(String.format("已成功接收到银行通知，" +
                    ":%s", request.getRequestURI()));
            String pabReqXml = StreamUtil.getBodyString(request.getInputStream(),Charset.forName("GBK"));
            logger.info(String.format("收到来自平安银行的通知:%s", pabReqXml));
            String returnXml = bankPabService.dealPabCallReq(pabReqXml);
            logger.info(String.format("已处理来自平台银行的通知:%s", returnXml));
            response.setCharacterEncoding("GBK");//设置字符集为'GBK'
            response.setContentType("application/xml");//设置格式为xml 
            PrintWriter write = response.getWriter();
            write.write(returnXml);
            write.flush();
            write.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 单笔转账
     */
    @PostMapping(value = "singleTrade")
    @EncryptInterceptor
    public ReturnData singleTrade(PabTradeRecord tradeRecord) {
        if (tradeRecord.getTradeNo() == null) tradeRecord.setTradeNo(DateTimeUtil.dateNo("TN"));
        if (tradeRecord.getOutBankShortName() == null || tradeRecord.getInBankShortName() == null) tradeRecord.setUnionFlag(true);
        tradeRecord.setUnionFlag(!tradeRecord.getOutBankShortName().equals(tradeRecord.getInBankShortName()));
        PabTradeRecord pabTradeRecord = bankPabService.singleTrade(tradeRecord);
        return jsonView(true, "交易发起成功",pabTradeRecord);
    }

    /**
     * 批量转账
     */
    @PostMapping(value = "batchTrade")
    @EncryptInterceptor
    public ReturnData batchTrade(String tradeRecordListJson) {
        List<PabTradeRecord> tradeRecordList = JsonUtil.jsonToObject(tradeRecordListJson,new TypeToken<List<PabTradeRecord>>(){});
        for (PabTradeRecord tradeRecord : tradeRecordList) {
            if (tradeRecord.getTradeNo() == null) tradeRecord.setTradeNo(DateTimeUtil.dateNo("TN"));
            if (tradeRecord.getOutBankShortName() == null || tradeRecord.getInBankShortName() == null) tradeRecord.setUnionFlag(true);
            tradeRecord.setUnionFlag(!tradeRecord.getOutBankShortName().equals(tradeRecord.getInBankShortName()));
        }
        String batchTradeNo = bankPabService.batchTrade(tradeRecordList);
        return jsonView(true, "交易发起成功",batchTradeNo);
    }

    /**
     * 获取交易记录列表
     */
    @PostMapping(value = "getTradeRecordPage")
    @EncryptInterceptor
    public ReturnData<PageData<PabTradeRecord>> getTradeRecordPage(PabTradeRecord.PabTradeStatus pabTradeStatus,
                                                                   String inAcctName,Integer page, Integer limit) {
        PageData<PabTradeRecord> tradeRecordPage = bankPabService.getTradeRecordPage(pabTradeStatus,inAcctName, page, limit);
        return jsonView(true, "查询成功", tradeRecordPage);
    }

    /**
     * 单笔转账查询
     */
    @PostMapping(value = "singleQueryTrade")
    @EncryptInterceptor
    public ReturnData singleQueryTrade(String tradeNo) {
        ResBody4005 resBody4005 = bankPabService.singleQueryTrade(tradeNo);
        return jsonView(true, "查询成功", resBody4005);
    }

    /**
     * 批量转账查询
     */
    @PostMapping(value = "batchQueryTrade")
    @EncryptInterceptor
    public ReturnData batchQueryTrade(String batchNo, String queryType, Integer page, Integer limit) {
        ResBody4015 resBody4015 = bankPabService.batchQueryTrade(batchNo, queryType, page, limit);
        return jsonView(true, "查询成功", resBody4015);
    }

    /**
     * 交易流水查询
     */
    @PostMapping(value = "queryTradeDetails")
    @EncryptInterceptor
    public ReturnData queryTradeDetails(String bankAccountNo, Date startDate, Date endDate, Integer page, Integer limit) {
        ResBody4013 resBody4013 = bankPabService.queryTradeDetails(bankAccountNo, startDate, endDate, page, limit);
        return jsonView(true, "查询成功", resBody4013);
    }

    /**
     * 账户余额查询
     */
    @PostMapping(value = "queryAccount")
    @EncryptInterceptor
    public ReturnData queryAccount(String bankAccountNo) {
        ResBody4001 resBody4001 = bankPabService.queryAccount(bankAccountNo);
        return jsonView(true, "查询成功", resBody4001);
    }

    /**
     * 银行流水下载
     */
    @PostMapping(value = "reqTradeDetailsDownloadList")
    @EncryptInterceptor
    public ReturnData reqTradeDetailsDownloadList(Date queryDate, String bankAccountNo, String bsnCode) {
        ResBodyF00101 resBodyF00101 = bankPabService.reqTradeDetailsDownloadList(queryDate, bankAccountNo, bsnCode);
        return jsonView(true, "查询成功", resBodyF00101);
    }

    /**
     * 获取PDF电子回单列表
     */
    @PostMapping(value = "reqTradeReceiptList")
    @EncryptInterceptor
    public ReturnData reqTradeReceiptList(String outAccNo, Date beginDate, Date endDate, String inAccNo, Integer page, Integer limit) {
        String nowDateStr = DateTimeUtil.dateToString(new Date(), "yyyyMMdd");
        String beginDateStr = DateTimeUtil.dateToString(beginDate, "yyyyMMdd");
        String endDateStr = DateTimeUtil.dateToString(endDate, "yyyyMMdd");
        if (beginDate!=null || endDate!=null) if (endDateStr.equals(nowDateStr) && !beginDateStr.equals(nowDateStr)) return jsonErrView("当日数据不能和历史数据混查");
        if (beginDateStr.equals(endDateStr) && endDateStr.equals(nowDateStr)) beginDate = endDate = null;
        ResBodyELC009 resBodyELC009 = bankPabService.reqTradeReceiptList(outAccNo, beginDate, endDate, inAccNo, page, limit);
        return jsonView(true, "查询成功", resBodyELC009);
    }

    /**
     * 创建电子回单PDF下载文件
     */
    @PostMapping(value = "createReceiptDownloadPDF")
    @EncryptInterceptor
    public ReturnData createReceiptDownloadPDF(String outAccNo, Date beginDate, Date endDate, String pdfNum, String itemListJson) {
        if (itemListJson==null || !JsonUtil.isJson(itemListJson)) return jsonErrView("回单子项传入解析错误");
        String nowDateStr = DateTimeUtil.dateToString(new Date(), "yyyyMMdd");
        String beginDateStr = DateTimeUtil.dateToString(beginDate, "yyyyMMdd");
        String endDateStr = DateTimeUtil.dateToString(endDate, "yyyyMMdd");
        if (beginDateStr.equals(endDateStr) && endDateStr.equals(nowDateStr)) beginDate = endDate = null;
        List<ReqBodyELC010.ReqBodyELC010Item> list = JsonUtil.jsonToObject(itemListJson,new TypeToken< List<ReqBodyELC010.ReqBodyELC010Item>>(){});
        ResBodyELC010 resBodyELC010 = bankPabService.createReceiptDownloadPDF(outAccNo, beginDate, endDate, pdfNum, list);
        return jsonView(true, "创建操作成功", resBodyELC010);
    }

    /**
     * 银行公共文件请求下载
     */
    @PostMapping(value = "reqDownloadTradeDetails")
    @EncryptInterceptor
    public ReturnData reqDownloadTradeDetails(String fileName, String randomPwd) {
        ResBodyFILE03 resBodyFILE03 = bankPabService.reqDownloadTradeDetails(fileName, randomPwd);
        return jsonView(true, "请求下载成功", resBodyFILE03);
    }

    /**
     * 下载任务列表[本地]
     */
    @PostMapping(value = "getDownloadTaskPage")
    @EncryptInterceptor
    public ReturnData getDownloadTaskPage(Integer page, Integer limit) {
        PageData<PabFileDownLoad> pabFileDownLoadList = bankPabService.getPabFileDownLoadList(page, limit);
        return jsonView(true, "查询成功", pabFileDownLoadList);
    }

    /**
     * 获取文件地址
     */
    @PostMapping(value = "generateFileDownloadUrl")
    @EncryptInterceptor
    public ReturnData generateFileDownloadUrl(String fileName) {
        String downloadUrl = bankPabService.generateFileDownload(fileName);
        return jsonView(true, "获取成功", downloadUrl);
    }

    /**
     * 银行对账列表
     */
    @PostMapping(value = "getTradeReconPage")
    @EncryptInterceptor
    public ReturnData getTradeReconPage(String outAccNo, Date queryDate, String checkFlag, Integer page, Integer limit) {
        ResBodyEDZ001 tradeReconPage = bankPabService.getTradeReconPage(outAccNo, queryDate, checkFlag, page, limit);
        return jsonView(true, "查询成功", tradeReconPage);
    }

    /**
     * 银行对账同步
     */
    @PostMapping(value = "syncTradeResult")
    @EncryptInterceptor
    public ReturnData syncTradeResult(String acctNo, String balanceDate,String itemListJson) {
        if (itemListJson==null || !JsonUtil.isJson(itemListJson)) return jsonErrView("对账子项传入解析错误");
        List<ReqBodyEDZ002.ReqBodyEDZ002Item> itemList = JsonUtil.jsonToObject(itemListJson,new TypeToken<List<ReqBodyEDZ002.ReqBodyEDZ002Item>>(){});
        ResBodyEDZ002 resBodyEDZ002 = bankPabService.syncTradeResult(acctNo, balanceDate, itemList);
        return jsonView(true, "操作成功", resBodyEDZ002);
    }

    /**
     * 系统日志列表
     */
    @PostMapping(value = "getDockingLogPage")
    @EncryptInterceptor
    public ReturnData getDockingLogPage(Integer page, Integer limit) {
        PageData<PabDockingLog> dockingLogPage = bankPabService.getDockingLogPage(page, limit);
        return jsonView(true, "查询成功", dockingLogPage);
    }

    /**
     * 服务器状态
     * */
    @PostMapping(value = "getServerStatusBag")
    @EncryptInterceptor
    public ReturnData<Map<String,String>> getServerStatusBag(){
        Map<String,String> serverStatusBag = bankPabService.getServerStatusBag();
        return jsonView(true, "查询成功", serverStatusBag);
    }

}
